home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / admin / sudo-1.000 / sudo-1 / sudo-1.2 / visudoers / visudo.c < prev    next >
C/C++ Source or Header  |  1993-06-11  |  5KB  |  178 lines

  1. /*
  2.  *  sudo version 1.1 allows users to execute commands as root
  3.  *  Copyright (C) 1991  The Root Group, Inc.
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 1, or (at your option)
  8.  *  any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; if not, write to the Free Software
  17.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  *  If you make modifications to the source, we would be happy to have
  20.  *  them to include in future releases.  Feel free to send them to:
  21.  *      Jeff Nieusma                       nieusma@rootgroup.com
  22.  *      3959 Arbol CT                      (303) 447-8093
  23.  *      Boulder, CO 80301-1752             
  24.  *
  25. ********************************************************************************
  26. * visudo.c, sudo project
  27. * David R. Hieb
  28. * March 18, 1991
  29. *
  30. * edit, lock and parse the sudoers file in a fashion similiar to /etc/vipw.
  31. *******************************************************************************/
  32. #include <sys/types.h>
  33. #include <sys/stat.h>
  34. #include <sys/file.h>
  35. #include <stdio.h>
  36. #include <errno.h>
  37. #include <signal.h>
  38.  
  39. #include "sudo.h"
  40.  
  41. extern    FILE *yyin, *yyout;
  42. extern    int errno, yylineno;
  43.  
  44. char    buffer[BUFSIZ];
  45. char    *sudoers = SUDOERS;
  46. int    status = 0, err_line_no = 0;
  47. char    *sudoers_tmp_file = TMPSUDOERS;
  48. FILE    *sudoers_tmp_fp, *sudoers_fp;
  49.  
  50. void Exit()
  51. {
  52. fclose(sudoers_tmp_fp);
  53. unlink(sudoers_tmp_file);
  54. exit(1);
  55. }
  56.  
  57. main(argc, argv)
  58. int argc;
  59. char **argv;
  60. {
  61. int fd;
  62. struct stat sbuf;
  63.  
  64. /* handle the signals */
  65. signal(SIGILL, Exit);
  66. signal(SIGTRAP, Exit);
  67. signal(SIGBUS, Exit);
  68. signal(SIGSEGV, Exit);
  69. signal(SIGTERM, Exit);
  70.  
  71. signal(SIGHUP, SIG_IGN);
  72. signal(SIGINT, SIG_IGN);
  73. signal(SIGQUIT, SIG_IGN);
  74.  
  75. setbuf(stderr, NULL);
  76.  
  77. /* we only want root to be able to read/write the sudoers_tmp_file */
  78. umask(077);
  79.  
  80. /* open the sudoers file read only */
  81. if ((sudoers_fp = fopen(sudoers, "r")) == NULL) {
  82.     fprintf(stderr, "%s: ", *argv); 
  83.     perror(sudoers);
  84.     Exit();
  85.     }
  86.  
  87. /* open the temporary sudoers file with the correct flags */
  88. if ((fd = open(sudoers_tmp_file, O_WRONLY|O_CREAT|O_EXCL, 0600)) < 0) {
  89.     if (errno == EEXIST) {
  90.         fprintf(stderr, "%s: sudoers file busy\n", *argv);
  91.         exit(1);
  92.         }
  93.     fprintf(stderr, "%s: ", *argv); 
  94.     perror(sudoers_tmp_file);
  95.     exit(1);
  96.     }
  97.  
  98. /* get a STREAM file pointer to the temporary sudoers file */
  99. if ((sudoers_tmp_fp = fdopen(fd, "w")) == NULL) {
  100.     fprintf(stderr, "%s: ", *argv); 
  101.     perror(sudoers_tmp_file);
  102.     Exit();
  103.     }
  104.  
  105. /* transfer the contents of the sudoers file to the temporary sudoers file */
  106. while (fgets(buffer, sizeof(buffer) - 1, sudoers_fp) != NULL) {
  107.     fputs(buffer, sudoers_tmp_fp);
  108.     }
  109.  
  110. fclose(sudoers_fp);
  111. fclose(sudoers_tmp_fp);
  112.  
  113. do {
  114.     /* build strings in buffer to be executed by system() */
  115.     sprintf(buffer, "%s +%d %s", EDITOR, err_line_no, sudoers_tmp_file);
  116.  
  117.     /* edit the file */
  118.     if (system(buffer) == 0) {
  119.  
  120.         /* can't stat file */
  121.         if (stat(sudoers_tmp_file, &sbuf) < 0) {
  122.             fprintf(stderr, "%s: can't stat temporary file, %s unchanged\n", 
  123.                 sudoers, *argv);
  124.             Exit();
  125.             }
  126.         /* file has size == 0 */
  127.         if (sbuf.st_size == 0) {
  128.             fprintf(stderr, "%s: bad temporary file, %s unchanged\n", 
  129.                 sudoers, *argv);
  130.             Exit();
  131.             }
  132.         /* re-open the sudoers file for parsing */
  133.         if ((sudoers_tmp_fp = fopen(sudoers_tmp_file, "r")) == NULL) {
  134.             fprintf(stderr, "%s: can't re-open temporary file, %s unchanged\n", 
  135.                 sudoers, *argv);
  136.             Exit();
  137.             }
  138.  
  139.         yyin = sudoers_tmp_fp;
  140.         yyout = stdout;
  141.          
  142.         /* parse the file */
  143.         if (yyparse()) {
  144.             fprintf(stderr, "yyparse() failed\n");
  145.             Exit();
  146.             }
  147.  
  148.         /*
  149.          * the first time we get an error, set status to yylineno which
  150.          * will be the line number after the line with the error.
  151.          * then, if we have gotten an error, set err_line_no to the
  152.          * correct line so that when we edit the file err_line_no will
  153.          * be correct. at this time we also reset status and yylineno
  154.          * to their default values so that the next time yyparse() is
  155.          * called, they will be initialized correctly.
  156.          */
  157.         err_line_no = (status == 0) ? 0 : status - 1;
  158.         status = 0;
  159.         yylineno = 1;
  160.  
  161.         fclose(sudoers_tmp_fp);
  162.         }
  163.     } while (err_line_no);
  164.  
  165. /* once the temporary sudoers file is gramatically correct, we can 
  166.  * rename it to the real sudoers file.
  167.  */
  168. if (rename(sudoers_tmp_file, sudoers) != 0) {
  169.     fprintf(stderr, "%s: ", *argv), perror("rename");
  170.     }
  171. else {
  172.     if (chmod(sudoers, 0400) != 0) {
  173.         perror("chmod: failed");
  174.         }
  175.     exit(0);
  176.     }
  177. }
  178.